package val.to.UI;

import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import val.to.Globals;
import val.to.ImageCache;
import val.to.R;
import val.to.SessionEvents;
import val.to.SessionEvents.LogoutListener;
import val.to.Utility;
import val.to.ValtoServices;
import val.to.UI.components.PullToRefreshListView;
import val.to.UI.components.PullToRefreshListView.OnRefreshListener;
import val.to.common.ITaskCanceler;
import val.to.common.ImageFetcher;
import val.to.common.ImageFetcher.ImageFetcherListener;
import val.to.common.SimpleTaskCanceler;
import val.to.common.SingleItemViewAdapter;
import val.to.config.Constants;
import val.to.entities.DisplayMode;
import val.to.entities.Event;
import val.to.entities.FeedFilterType;
import val.to.entities.FeedItem;
import val.to.server.IServerPortal.FeedUpdate;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.HeaderViewListAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.SlidingDrawer;
import android.widget.SlidingDrawer.OnDrawerScrollListener;
import android.widget.TextView;
import android.widget.Toast;

public class NewsFeed extends Activity {

	private static class State {
		public SoftReference<ArrayList<FeedItem>> items;
		public Date lastUpdate;
		public int eventId;
		public String lastError;
	}

	final int GALLERY_ACTIVITY_REQUEST_CODE = 101;
	final int CAPTURE_PHOTO_ACTIVITY_REQUEST_CODE = 103;
	final int CREATE_EVENT_ACTIVITY_REQUEST_CODE = 104;
	final int EVENT_INFO_ACTIVITY_REQUEST_CODE = 105;

	Handler mHandler;

	private ImageButton mGalleryButton;
	private ImageButton mCapturePhotoButton;
	private Button mFilterByFriendsButton;
	private Button mFilterNone;
	private Button mFilterByMine;
	private Button mCheckinButton;
	private Button mShareEventButton;
	private Button mChangeFeedStyle;
	private ProgressBar mProgressBar;
	
	private ImageView mHandle;
	private SlidingDrawer mSlider;

	// Header controls
	private TextView mEventName;
	private PullToRefreshListView mFeedList;
	private Date mDateRef;
	private boolean mClearAdapter;

	private ItemAdapter mItemAdapter;
	private FeedItemsAdapter mListAdapter;
	private AlbumItemsAdapter mGridAdapter;
	private GetMoreItemsTask mUpdateTask;
	private ITaskCanceler mTaskCanceler;
	private static Uri mCapturedImageUri;

	private MenuButton mMenuButton;
	private Set<String> mErrors = new HashSet<String>();

	private static State smState;
	private String mLastError;
	private int mScreenWidth;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.news_feed);

		SessionEvents.addLogoutListener(new LogoutListener() {

			@Override
			public void onLogoutFinish() {
				mFeedList.setAdapter(null);
			}

			@Override
			public void onLogoutBegin() {

			}
		});

		mHandler = new Handler();
		InitUIComponents();
	}

	private Adapter currentAdapter() {
		if (mFeedList.getAdapter() == null) {
			return null;
		}
		HeaderViewListAdapter hvla = (HeaderViewListAdapter) mFeedList
				.getAdapter();
		return hvla.getWrappedAdapter();
	}

	private void InitUIComponents() {
		// connect UI components to local variables
		mCapturePhotoButton = (ImageButton) findViewById(R.id.captureBtn);
		mGalleryButton = (ImageButton) findViewById(R.id.galleryBtn);
		mCheckinButton = (Button) findViewById(R.id.btn_check_in);
		mFilterByFriendsButton = (Button) findViewById(R.id.btn_filter_by_friends);
		mFilterByMine = (Button) findViewById(R.id.btn_filter_mine);
		mFilterNone = (Button) findViewById(R.id.btn_filter_none);
		mShareEventButton = (Button) findViewById(R.id.btn_share_event);
		mFeedList = (PullToRefreshListView) findViewById(R.id.feedList);
		mEventName = (TextView) findViewById(R.id.name);
		mMenuButton = (MenuButton) findViewById(R.id.menuButton);
		mProgressBar = (ProgressBar) findViewById(R.id.action_progress);
		mChangeFeedStyle = (Button) findViewById(R.id.changeFeedStyle);
		mHandle = (ImageView) findViewById(R.id.handle);
		mSlider = (SlidingDrawer) findViewById(R.id.sliding_drawer);
		
		mMenuButton.init(this);
		mProgressBar.setVisibility(View.GONE);

		// TODO: move to layout.xml
		mFeedList.setDivider(null);
		mFeedList.setDividerHeight(0);
		
		//TODO: TEMP
		//mChangeFeedStyle.setVisibility(View.GONE);
		//mShareEventButton.setVisibility(View.GONE);


	  mSlider.setOnDrawerScrollListener(new OnDrawerScrollListener(){
          @Override
          public void onScrollEnded() {
        	  //mHandle.setImageResource(mSlider.isOpened() ? R.drawable.scroll_up_arrow : R.drawable.scroll_down_arrow);
          }

          @Override
          public void onScrollStarted() {
          }
	  });
	
		// create listeners
		mEventName.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Event event = ValtoServices.getCurrentEvent();
				Intent intent = new Intent(v.getContext(),
						EventDetailsActivity.class);

				Bundle b = new Bundle();
				b.putParcelable("val.to.entities.Event", event);

				intent.putExtras(b);
				startActivity(intent);
			}
		});

		mChangeFeedStyle.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				int eventId = ValtoServices.getCurrentEvent().getId();
				DisplayMode mode = ValtoServices.nextDisplayMode(eventId);
				refreshDisplayModeButton(mode);

				mFeedList.setAdapter(mItemAdapter);
				mSlider.close();
			}
		});

		mCapturePhotoButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				CapturePhoto();
			}
		});

		mGalleryButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent i = new Intent(
						Intent.ACTION_PICK,
						android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
				startActivityForResult(i, GALLERY_ACTIVITY_REQUEST_CODE);
			}
		});

		mFilterByFriendsButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (setFilter(FeedFilterType.Friends)){
					mSlider.close();
					Toast.makeText(NewsFeed.this, R.string.friends_filter_enabled, Toast.LENGTH_SHORT).show();
				}
			}
		});
		
		mFilterByMine.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (setFilter(FeedFilterType.Mine)){
					mSlider.close();
					Toast.makeText(NewsFeed.this, R.string.mine_filter_enabled, Toast.LENGTH_SHORT).show();
				}
			}
		});
		
		mFilterNone.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (setFilter(FeedFilterType.None)){
					mSlider.close();
					Toast.makeText(NewsFeed.this, R.string.none_filter_enabled, Toast.LENGTH_SHORT).show();
				}
			}
		});

		mCheckinButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				int eventId = ValtoServices.getCurrentEvent().getId();
				if (ValtoServices.isCheckedIntoEvent(eventId)) {
					Toast.makeText(NewsFeed.this, R.string.already_checked_in,
							Toast.LENGTH_SHORT).show();
				} else {
					new CheckIntoCurrentEventTask().execute();
					mSlider.close();
				}
			}
		});

		mShareEventButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				int eventId = ValtoServices.getCurrentEvent().getId();
				if (ValtoServices.isEventShared(eventId)) {
					Toast.makeText(NewsFeed.this, R.string.already_shared,
							Toast.LENGTH_SHORT).show();
				} else {
					new ShareEventTask(eventId).execute();
					mSlider.close();
				}
			}
		});

		mFeedList.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> adapterView, View view,
					int position, long l) {
				Adapter adapter = currentAdapter();
				/*
				 * 0 if header was clicked , ignore
				 */
				if (adapter instanceof FeedItemsAdapter && position >= 1) {
					Intent i = new Intent(getApplicationContext(),
							ItemFullScreenActivity.class);
					i.putExtra("CurrentItem", position - 1 /*
															 * include the
															 * header
															 */);
					i.putParcelableArrayListExtra("FeedItems",
							((FeedItemsAdapter) adapter).getItems());

					startActivity(i);
				}
			}
		});
	}
	
	private void refreshDisplayModeButton(DisplayMode mode){
		if (mode == DisplayMode.Album) {
			mItemAdapter = mGridAdapter;
			mChangeFeedStyle.setText(R.string.btn_change_to_feed);
			mFeedList.setClickable(false);
		} else {
			mItemAdapter = mListAdapter;
			mChangeFeedStyle.setText(R.string.btn_change_to_album);
			mFeedList.setClickable(true);
		}
	}
	
	private boolean setFilter(FeedFilterType filter){
		if (mUpdateTask != null) {
			// Wait till the current task finishes.
			return false;
		}

		int eventId = ValtoServices.getCurrentEvent().getId();
		if (ValtoServices.setFilterType(eventId, filter)){
			//The filter was changed indeed.
			followEvent(ValtoServices.getCurrentEvent(), null);
			showCurrentFilter(eventId);
			
			return true;
		}
		
		return false;
	}

	@Override
	protected void onPause() {
		super.onPause();

		if (mUpdateTask != null) {
			mUpdateTask.cancel(true);
		}

		if (mTaskCanceler != null) {
			mTaskCanceler.cancel();
		}

		// Save the current state.
		State currentState = new State();
		currentState.items = mItemAdapter != null ? new SoftReference<ArrayList<FeedItem>>(
				mItemAdapter.getItems()) : null;
		currentState.eventId = ValtoServices.getCurrentEvent().getId();
		currentState.lastUpdate = mFeedList.getLastUpdate();
		currentState.lastError = mLastError;
	
		smState = currentState;
	}

	@Override
	public void onResume() {
		super.onResume();
		Globals.FacebookSession.extendAccessTokenIfNeeded(this, null);

		Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
		mScreenWidth = display.getWidth();
		
		if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
			//Hide the slider
			mSlider.setVisibility(View.GONE);
		}

		Event currentEvent = ValtoServices.getCurrentEvent();
		State state = smState;
		smState = null; // Let the smState be GCed

		if (currentEvent == null) {
			onNoEventSelected();
		} else if (state == null || (state.eventId != currentEvent.getId())) {
			// First time or new event was selected.
			followEvent(currentEvent, null);
		} else if (state != null) {
		
			// Same event, restore the items or the error
			if (state.lastError == null) {
				followEvent(currentEvent, state.items.get());
				mFeedList.setLastUpdate(state.lastUpdate);
			} else {
				mLastError = state.lastError;
				mFeedList.setAdapter(new SingleItemViewAdapter(NewsFeed.this,
						R.string.error_loading_feed, false,
						R.drawable.error_bw, mLastError));
			}
		}

		enableButtons(currentEvent != null);
		refreshCheckInButton(currentEvent.getId());
		showCurrentFilter(currentEvent.getId());
		refreshShareButton(currentEvent.getId());
		refreshDisplayModeButton(ValtoServices.getDisplayMode(currentEvent.getId()));
		
		if (currentEvent != null) {
			mFeedList.setOnRefreshListener(new OnRefreshListener() {
				@Override
				public void onRefresh() {
					if (mUpdateTask == null) {
						int eventId = ValtoServices.getCurrentEvent().getId();
						FeedFilterType filter = ValtoServices.getFilterType(eventId);
						new NewsFeed.GetMoreItemsTask(filter).execute();
					}
				}
			});
		} else {
			mFeedList.setOnRefreshListener(null);
		}
	}

	private void enableButtons(boolean enable) {
		mGalleryButton.setEnabled(enable);
		mCapturePhotoButton.setEnabled(enable);
		mEventName.setEnabled(enable);
		mFilterByFriendsButton.setEnabled(enable);
		mCheckinButton.setEnabled(enable);
	}

	private void onNoEventSelected() {
		if (mTaskCanceler != null) {
			mTaskCanceler.cancel();
		}

		if (mUpdateTask != null) {
			mUpdateTask.cancel(true);
			mUpdateTask = null;
		}

		mEventName.setText("");
		mFeedList.setAdapter(new SingleItemViewAdapter(this,
				R.string.SelectEventFirst, false));
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		if (requestCode == GALLERY_ACTIVITY_REQUEST_CODE
				|| requestCode == CAPTURE_PHOTO_ACTIVITY_REQUEST_CODE) {
			if (resultCode == RESULT_OK) {
				Uri uri;
				if (data != null)
					uri = data.getData();
				else
					uri = mCapturedImageUri;
				Intent uploadIntent = new Intent(this, PhotoUpload.class);
				uploadIntent.putExtra("photoUrl", uri);
				startActivityForResult(uploadIntent, 1234123);
				// startActivity(uploadIntent);
			} else if (resultCode == RESULT_CANCELED) {
				// Do nothing
			} else {
				Toast.makeText(this, "Error", Toast.LENGTH_LONG).show();
			}
		}
	}

	private void CapturePhoto() {
		// create Intent to take a picture and return control to the calling
		// application

		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		// create a file to save the image
		mCapturedImageUri = Utility
				.getOutputMediaFileUri(getString(R.string.ValtoCameraFolder));
		if (mCapturedImageUri == null) {
			Toast.makeText(
					this,
					"Valto failed to create local directory for the captured photos",
					Toast.LENGTH_LONG).show();
			return;
		}
		// set the image file name
		intent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageUri);
		// start the image capture Intent
		startActivityForResult(intent, CAPTURE_PHOTO_ACTIVITY_REQUEST_CODE);
	}

	private void followEvent(Event event, ArrayList<FeedItem> items) {
		if (mTaskCanceler != null) {
			mTaskCanceler.cancel();
		}

		if (mUpdateTask != null) {
			mUpdateTask.cancel(true);
			mUpdateTask = null;
		}

		mErrors.clear();
		mListAdapter = new FeedItemsAdapter();
		mGridAdapter = new AlbumItemsAdapter();
		if (ValtoServices.getDisplayMode(event.getId()) == DisplayMode.Album) {
			mItemAdapter = mGridAdapter;
		} else {
			mItemAdapter = mListAdapter;
		}

		mDateRef = null;
		mEventName.setText(event.getName());
		mTaskCanceler = new SimpleTaskCanceler();
		mClearAdapter = false;

		if (items != null) {
			if (items.size() > 0) {
				mGridAdapter.updateItems(items, null);
				mListAdapter.updateItems(items, null);
				mFeedList.setAdapter(mItemAdapter);
				mDateRef = items.get(0).getTimestamp();
			} else {
				onNoPhotos();
			}
		} else {
			mFeedList.setAdapter(null);
			mFeedList.setRefreshing();
			FeedFilterType friendsOnly = ValtoServices.getFilterType(event.getId());
			new NewsFeed.GetMoreItemsTask(friendsOnly).execute();
		}
	}

	private void showCurrentFilter(int eventId) {
		FeedFilterType filter = ValtoServices.getFilterType(eventId);		
		Drawable check = getResources().getDrawable(R.drawable.small_check);
		
		mFilterByFriendsButton.setCompoundDrawablesWithIntrinsicBounds(filter == FeedFilterType.Friends ? check : null, null, null, null);
		mFilterNone.setCompoundDrawablesWithIntrinsicBounds(filter == FeedFilterType.None ? check : null, null, null, null);
		mFilterByMine.setCompoundDrawablesWithIntrinsicBounds(filter == FeedFilterType.Mine ? check : null, null, null, null);
	}

	private void refreshCheckInButton(int eventId) {
		/*
		
		if (ValtoServices.isCheckedIntoEvent(eventId)) {
			mCheckinButton.setImageResource(R.drawable.check_in_on);
		} else {
			mCheckinButton.setImageResource(R.drawable.check_in_off);
		}
		
		*/
	}

	private void refreshShareButton(int eventId) {
	/*
		if (ValtoServices.isEventShared(eventId)) {
			mShareEventButton.setImageResource(R.drawable.share_on);
		} else {
			mShareEventButton.setImageResource(R.drawable.share_off);
		}
	*/
	}

	private class FeedItemsAdapter extends ItemAdapter {
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			final FeedItem item = (FeedItem) getItem(position);

			if (convertView == null) {
				LayoutInflater inflater = (LayoutInflater) NewsFeed.this.getLayoutInflater();
				convertView = inflater.inflate(R.layout.feed_item_view, null);
			}

			TextView comment = (TextView) convertView.findViewById(R.id.comment);
			TextView username = (TextView) convertView.findViewById(R.id.username);
			TextView timeAgo = (TextView) convertView.findViewById(R.id.timeago);
			final ImageView thumbnail = (ImageView) convertView.findViewById(R.id.thumbnail);
			final ImageView userImage = (ImageView) convertView.findViewById(R.id.userImage);
			ImageView delete = (ImageView) convertView.findViewById(R.id.delete_photo);
			final String userGraphPath = String.format(Constants.FB_User_Image_Template, item.getUserId());

			thumbnail.setTag(item.getSmallPhotoUri());
			userImage.setTag(userGraphPath);
			delete.setVisibility(item.getEditable() ? View.VISIBLE : View.GONE);

			delete.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					AlertDialog.Builder builder = new AlertDialog.Builder(
							NewsFeed.this);
					builder.setMessage(R.string.confirm_delete)
							.setCancelable(false)
							.setPositiveButton("Yes",
									new DialogInterface.OnClickListener() {
										public void onClick(
												DialogInterface dialog, int id) {
											dialog.dismiss();

											// First delete from the list
											boolean isEmpty = !mGridAdapter.remove(item);
											mListAdapter.remove(item);
											mItemAdapter.notifyDataSetChanged();

											// Start worker thread to delete
											// from the server
											new DeleteItemTask(item).execute();
											
											if (isEmpty){
												onNoPhotos();
											}

											// NOTE: in case of failure while
											// deleting from the server,
											// the photo still disappears from
											// the client's list.
										}
									})
							.setNegativeButton("No",
									new DialogInterface.OnClickListener() {
										public void onClick(
												DialogInterface dialog, int id) {
											dialog.cancel();
										}
									});
					builder.show();
				}
			});

			if (item.getComment() == null || item.getComment().length() == 0) {
				comment.setVisibility(View.GONE);
			} else {
				comment.setVisibility(View.VISIBLE);
			}

			Bitmap userBmp = ImageCache.getInstanceUserPictures().tryGetBitmap(userGraphPath);
			if (userBmp != null) {
				userImage.setImageBitmap(userBmp);
			} else {
				downloadImageAsync(userImage, userGraphPath, item, ImageCache.getInstanceUserPictures());
			}

			if (mErrors.contains(item.getSmallPhotoUri())) {
				thumbnail.setImageResource(R.drawable.error_bw);
			} else {
				Bitmap bmp = ImageCache.getInstanceSmallPhotos().tryGetBitmap(item.getSmallPhotoUri());
				if (bmp != null) {
					thumbnail.setImageBitmap(bmp);
				} else {
					final String uri = item.getSmallPhotoUri();
					downloadImageAsync(thumbnail, uri, item, ImageCache.getInstanceSmallPhotos());		
				}
			}

			comment.setText(item.getComment());
			username.setText(item.getUsername());

			String str = Utility.getRoughStringForTimeDiff(item.getMscAgo());
			timeAgo.setText(str);

			return convertView;
		}
	}
	
	private void downloadImageAsync(final ImageView imageView, final String uri, FeedItem item, final ImageCache imageCache)
	{
		imageView.setImageBitmap(null);
		
		ImageFetcher fetcher = new ImageFetcher(uri, new ImageFetcherListener() {
			@Override
			public void onImageFetchCompleted(final Bitmap bmp) {
				
				if (imageCache != null){
					imageCache.encache(uri, bmp);
				}
				
				mHandle.post(new Runnable() {	
					@Override
					public void run() {
			
						if (imageView.getTag().toString().equals(uri)){    
							imageView.setImageBitmap(bmp);
						}
					}
				});
			}
		}, mTaskCanceler);
		

		Globals.AsyncTasksQueue.AddTask(fetcher);
	}

	private class AlbumItemsAdapter extends ItemAdapter {
		final int ItemPadding = 3;
		int mItemSize = 0;

		private class ViewHolder {
			public ArrayList<ImageView> Images;

			public ViewHolder() {
				Images = new ArrayList<ImageView>();
			}
		}

		private int ImagesPerRow() {
			int x = mScreenWidth / Constants.ALBUM_ITEM_MIN_SIZE;
			mItemSize = mScreenWidth / x;
			return x;
		}

		private void GoFullSize(int position) {
			Intent i = new Intent(getApplicationContext(),
					ItemFullScreenActivity.class);
			i.putExtra("CurrentItem", position);
			i.putParcelableArrayListExtra("FeedItems", getItems());
			startActivity(i);
		}

		@Override
		public int getCount() {
			int count = m_items.size() / ImagesPerRow();
			count = m_items.size() % ImagesPerRow() > 0 ? count + 1 : count;
			return count;
		}

		@Override
		public View getView(final int position, View convertView,
				ViewGroup parent) {
			if (convertView == null) {
				convertView = new LinearLayout(NewsFeed.this);
				((LinearLayout)convertView).setOnClickListener(new OnClickListener() {					
					@Override
					public void onClick(View v) {}
				});
				ViewHolder vh = new ViewHolder();
				for (int i = 0; i < ImagesPerRow(); i++) {
					final int ii = i;
					ImageView iv = new ImageView(NewsFeed.this);
					iv.setPadding(ItemPadding, ItemPadding, ItemPadding, ItemPadding);
					((LinearLayout) convertView).addView(iv, mItemSize,
							mItemSize);
					vh.Images.add(iv);
				}
				convertView.setTag(vh);
			}

			ArrayList<FeedItem> items = new ArrayList<FeedItem>();

			for (int i = 0; i < ImagesPerRow(); i++) {
				if (m_items.size() > position * ImagesPerRow() + i)
					items.add((FeedItem) getItem(position * ImagesPerRow() + i));
			}

			ViewHolder vh = (ViewHolder) convertView.getTag();
			for (int i = 0; i < ImagesPerRow(); i++) {
				final int ii = i;
				ImageView iv = vh.Images.get(i);
				iv.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						GoFullSize(position * ImagesPerRow() + ii);
					}
				});
				if (items.size() - 1 < i) {
					iv.setVisibility(View.GONE);
					iv.setTag("");
				} else {
					iv.setVisibility(View.VISIBLE);
					iv.setTag(items.get(i).getThumbnailPhotoUri());
					setImage(items.get(i), iv);
				}
			}
			return convertView;
		}

		//
		// if (convertView == null) {
		// ViewHolder vh = new ViewHolder();
		// convertView = mInflater.inflate(R.layout.album_row, null);
		// vh.Images[0] = (ImageView) convertView
		// .findViewById(R.id.imageView1);
		// vh.Images[1] = (ImageView) convertView
		// .findViewById(R.id.imageView2);
		// vh.Images[2] = (ImageView) convertView
		// .findViewById(R.id.imageView3);
		// vh.Images[3] = (ImageView) convertView
		// .findViewById(R.id.imageView4);
		// vh.Images[4] = (ImageView) convertView
		// .findViewById(R.id.imageView5);
		// convertView.setTag(vh);
		// }
		//
		// ViewHolder vh = (ViewHolder) convertView.getTag();
		// for (int i = 0; i < 5; i++) {
		// ImageView iv = vh.Images[i];
		// if (items.size() - 1 < i) {
		// iv.setVisibility(View.GONE);
		// iv.setTag("");
		// } else {
		// iv.setVisibility(View.VISIBLE);
		// iv.setTag(items.get(i).getThumbnailUri());
		// setImage(items.get(i), iv);
		// }
		// }
		// return convertView;
		// }

		private void setImage(FeedItem item, ImageView thumbnail) {
			if (mErrors.contains(item.getSmallPhotoUri())) {
				thumbnail.setImageResource(R.drawable.error_bw);
			} else {
				Bitmap bmp = ImageCache.getInstanceThumbnailsPhotos().tryGetBitmap(item.getThumbnailPhotoUri());
				if (bmp != null) {
					thumbnail.setImageBitmap(bmp);
				} else {
					String uri = item.getThumbnailPhotoUri();
					downloadImageAsync(thumbnail, uri, item, ImageCache.getInstanceThumbnailsPhotos());
				}
			}
		}
	}

	public class GetMoreItemsTask extends AsyncTask<Void, Void, Void> {
		private FeedUpdate mUpdate;
		private FeedFilterType mFilter;

		public GetMoreItemsTask(FeedFilterType filter) {
			mFilter = filter;
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			Globals.AsyncTasksQueue.ClearAllPendingTasks();
			mUpdateTask = this;
			if (mClearAdapter) {
				mFeedList.setAdapter(null);
			}
		}

		@Override
		protected Void doInBackground(Void... params) {

			try
			{
				// Request feed items
				mUpdate = ValtoServices.getFeedItems(mDateRef,
						Constants.MAX_FEED_ITEMS_PER_REFRESH, true, mFilter);
	
				if (mUpdate == null) {
					return null;
				}
	
				// Sort the new items
				if (mUpdate.newItems != null && mUpdate.newItems.size() > 0) {
					Collections.sort(mUpdate.newItems, new Comparator<FeedItem>() {
						@Override
						public int compare(FeedItem lhs, FeedItem rhs) {
							return (int) (lhs.getMscAgo() - rhs.getMscAgo()); // dsc
																				// order
						}
					});
				}
			}
			catch (Exception ex)
			{
				mUpdate = null;
			}

			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);

			try
			{
				mLastError = null;
				mClearAdapter = false;
				mUpdateTask = null;
				mFeedList.onRefreshComplete();
				if (isCancelled()) {
					// do nothing here.
					return;
				}
				
				if (mUpdate == null) {
					mLastError = ValtoServices.getLastServerError();
					mFeedList.setAdapter(new SingleItemViewAdapter(NewsFeed.this,
							R.string.error_loading_feed, false,
							R.drawable.error_bw, mLastError));
					mClearAdapter = true;
					return;
				}
	
				// Handle the new items
				if (mUpdate.newItems.size() > 0) {
					mDateRef = mUpdate.newItems.get(0).getTimestamp();
				}
	
				if (mListAdapter != null && mGridAdapter != null && mItemAdapter != null) {
					mListAdapter.updateItems(mUpdate.newItems, mUpdate.deletedItems);
					mGridAdapter.updateItems(mUpdate.newItems, mUpdate.deletedItems);
					if (currentAdapter() != mItemAdapter && mItemAdapter.getCount() > 0) {
						mFeedList.setAdapter(mItemAdapter);
					} else {
						if (mItemAdapter.getCount() == 0) {
							onNoPhotos();
						} else {
							mItemAdapter.notifyDataSetChanged();
						}
					}
				}
	
				refreshCheckInButton(ValtoServices.getCurrentEvent().getId());
			}
			catch (Exception ex)
			{
				
			}
		}
	}

	//@Override
	//public void onConfigurationChanged(Configuration newConfig) {		
	//	super.onConfigurationChanged(newConfig);
		
		//This will cause the screen rotation NOT to recreate the activity.
		//Some layout related re-styling must be done here.
	//}
	
	private void onNoPhotos(){
		mFeedList.setAdapter(new SingleItemViewAdapter(NewsFeed.this, R.string.no_photos, false));
		mClearAdapter = true;	
	}
	
	private static class DeleteItemTask extends AsyncTask<Void, Void, Void> {
		private FeedItem mItem;
		private boolean mResult;

		public DeleteItemTask(FeedItem item) {
			mItem = item;
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

		@Override
		protected Void doInBackground(Void... params) {
			mResult = ValtoServices.deletePhoto(mItem.getId());
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			if (!mResult) {
				Log.e(Constants.TAG,
						"Failed to delete item <" + mItem.toString()
								+ "> from the server");
			}
		}
	}

	private class ShareEventTask extends AsyncTask<Void, Void, Void> {
		private int mEventId;
		private boolean mResult;

		public ShareEventTask(int eventId) {
			mEventId = eventId;
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			mShareEventButton.setEnabled(false);
			mProgressBar.setVisibility(View.VISIBLE);
		}

		@Override
		protected Void doInBackground(Void... params) {
			mResult = ValtoServices.shareEvent(mEventId);
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			if (mResult) {
				refreshShareButton(mEventId);
				Toast.makeText(NewsFeed.this, R.string.share_confirm,
						Toast.LENGTH_SHORT).show();
			} else {
				Toast.makeText(NewsFeed.this, R.string.share_failed,
						Toast.LENGTH_SHORT).show();
			}

			mProgressBar.setVisibility(View.GONE);
			mShareEventButton.setEnabled(true);
		}
	}

	private class CheckIntoCurrentEventTask extends AsyncTask<Void, Void, Void> {
		private boolean mResult;

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			mCheckinButton.setEnabled(false);
			mProgressBar.setVisibility(View.VISIBLE);
		}

		@Override
		protected Void doInBackground(Void... params) {
			mResult = ValtoServices.checkIntoCurrentEvent(true);
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			if (mResult) {
				refreshCheckInButton(ValtoServices.getCurrentEvent().getId());
				Toast.makeText(NewsFeed.this, R.string.checkin_confirm,
						Toast.LENGTH_SHORT).show();
			} else {
				Toast.makeText(NewsFeed.this, R.string.checkin_failed,
						Toast.LENGTH_SHORT).show();
			}

			mProgressBar.setVisibility(View.GONE);
			mCheckinButton.setEnabled(true);
		}
	}
}